<script setup lang="ts">
import { getPlantQuarantine } from '@/api/agriculture.ts';
import type { pageItem } from '@/api/type/agriculture.ts';
import { PolicyListColTpl } from '@/components/table/_/PolicyList.ts';
import { useSearchStore } from '@/stores/searchTermData.ts';
import { ColumnType } from '@/types.local';
import { defineDataSource } from '@/utils/pinia';

defineOptions({
  inheritAttrs: false, // 允许用户透传属性到 TableBase
});

export type TableSoundListCol = keyof typeof PolicyListColTpl; // 预定义的列
export interface TableResourceListProps {
  data?: any['']; // 从外部传入数据，用于通过用户选中项创建表格等场景，如果传入则不使用内置的数据管理、使用前端分页
  req?: Omit<pageItem, 'pageNo' | 'pageSize'>; // 请求参数，外部可以通过这个参数控制表格数据的筛选; 这个值变化时会自动刷新数据
  cols?: TableSoundListCol[]; // 要显示的预定义列 ⚠️注意: 如果要使用 ColumnActionMore，不要在这里传入预定义的 action，而应该通过 append 插槽传入 ColumnAction 组件
}
const props = withDefaults(defineProps<TableResourceListProps>(), {
  req: () => {
    return {};
  },
  cols: () => ['name'],
});

const pageNo = defineModel<number>('pageNo', { default: 1 }); // 当前页码
const pageSize = defineModel<number>('pageSize', { default: 15 }); // 每页条数

type ColConfig = { t: ColumnType; v: any[] }[];
const combinedCols = computed<ColConfig>(() => {
  // 按顺序解析用户传入的 cols，获取对应列配置，并按类型合并相邻的列，便于传给 table-column 组件
  const ret: ColConfig = [];
  if (props.cols == null) return ret;

  let lastType: ColConfig[number]['t'] | null = null;
  let lastValue: any[] = [];
  for (const col of props.cols) {
    const { t, v } = PolicyListColTpl[col];
    if (t === lastType) {
      lastValue.push(v);
    } else {
      if (lastType != null) {
        ret.push({ t: lastType, v: lastValue });
      }
      lastType = t;
      lastValue = [v];
    }
  }
  if (lastType != null) {
    ret.push({ t: lastType, v: lastValue });
  }
  return ret;
});

// Pinia
const SearchStore = useSearchStore();
// 请求参数
const request = computed((): pageItem => {
  return {
    pageNo: pageNo.value,
    pageSize: pageSize.value,
    searchTerm: SearchStore.policySearch.searchTerm ?? '',
  };
});

watch(
  () => SearchStore.policySearch.searchTerm,
  (newSearchTerm) => {
    // 如果 searchTerm 有值，则设置 pageSize 为 40，否则恢复为 15
    if (newSearchTerm) {
      pageSize.value = 40;
    } else {
      pageSize.value = 15;
    }
  },
  { immediate: true }
);

// 监听请求参数变化
watchDeep(request, () => {
  refresh();
});

const {
  data: dataSource,
  loading,
  reload,
  err,
} = defineDataSource<any>(
  {
    data: [],
    meta: {
      pagination: {
        page: 0,
        pageSize: 0,
        pageCount: 0,
        total: 0,
      },
    },
  },
  () => getPlantQuarantine(request.value),
  {
    loadOnFirstVisit: true,
    resetOnError: true,
  }
);

watch(dataSource, () => {
  if (SearchStore.policySearch.searchTerm && dataSource.value.meta.pagination.total > 0) {
    ElMessage.success(
      `搜索'${SearchStore.policySearch.searchTerm}'成功，共 ${dataSource.value.meta.pagination.total} 条政策法规数据`
    );
  } else if (SearchStore.policySearch.searchTerm && dataSource.value.meta.pagination.total === 0) {
    ElMessage.warning(`暂无'${SearchStore.policySearch.searchTerm}'政策法规数据`);
  }
});

function refresh() {
  // 因为设置了 resetOnError，不用显示出错误
  reload().catch(() => {});
}

// 数据和总数变化时触发刷新
watch(
  () => [props.data],
  () => {
    refresh();
  },
  { deep: true }
);
</script>

<template>
  <div v-loading="loading">
    <TableBase
      v-model:page="pageNo"
      v-model:pageSize="pageSize"
      :data="dataSource.data"
      :total="dataSource.meta.pagination.total"
      :error-msg="data == null ? err : undefined"
      :retry-fn="refresh"
      :remote-pagin="data == null"
      v-bind="$attrs"
      with-index
    >
      <!-- 可以使用默认插槽覆盖所有预定义列 -->
      <slot>
        <template v-for="(c, i) in combinedCols" :key="i">
          <ColumnText v-if="c.t === ColumnType.Text" :columns="c.v" />
          <ColumnSwitch v-else-if="c.t === ColumnType.Switch" :columns="c.v" />
        </template>

        <!-- 可以使用 append 插槽扩展 cols，在末尾添加自定义列 -->
        <slot name="append"></slot>
      </slot>
    </TableBase>
  </div>
</template>

<style scoped></style>
